#include "vis_eth.h"





static int vis_net_open(struct net_device *ndev)
{
    netif_start_queue(ndev);
    return 0;
}

static int vis_net_stop(struct net_device *ndev)
{
    if(ndev)
        netif_stop_queue(ndev);
    return 0;
}

static netdev_tx_t vis_net_xmit(struct sk_buff *skb, struct net_device *ndev)
{
    struct vis_dev *vdev = netdev_priv(ndev);
    if(!vdev)
        return 0;

    return qdma_xmit(skb, vdev, int type, 0);

}

static void vis_net_tx_timeout(struct net_device *ndev)
{
    struct vis_dev *vdev;
    if(ndev) {
        vdev = netdev_priv(ndev);
        if(vdev) {
            vdev->stats.tx_errors++;
        }
        netif_wake_queue(ndev);
    }
}

static struct net_device_stats *vis_net_get_stats(struct net_device *ndev)
{
    struct vis_dev *vdev;
    struct net_device_stats *p_stats;
    struct qdma_h2c_queue *p_h2c;
    struct qdma_c2h_queue *p_c2h;
    u32 i;

    if(ndev) {
        vdev = netdev_priv(ndev);
        if(vdev) {
            p_stats = &vdev->stats;
            memset(p_stats, 0, sizeof(struct net_device_stats));

            for(i = 0; i < vdev->q_num; i++) {
                p_h2c = &(vdev->h2c_q[i]);
                p_stats->tx_packets += p_h2c->tx_packets;
                p_stats->tx_bytes   += p_h2c->tx_bytes;

                p_c2h = &(vdev->c2h_q[i]);
                p_stats->rx_packets += p_c2h->rx_packets;
                p_stats->rx_bytes   += p_c2h->rx_bytes;
            }
            return p_stats;
        }
    }
    return NULL;
}

static const struct net_device_ops vis_net_ops = {
    .ndo_open       = vis_net_open,
    .ndo_stop       = vis_net_stop,
    .ndo_start_xmit = vis_net_xmit,
    .ndo_tx_timeout = vis_net_tx_timeout,
    .ndo_get_stats  = visroce_net_get_stats,
    //.ndo_set_mac_address = eth_mac_addr,
};


static void vis_get_drvinfo(struct net_device *ndev,
    struct ethtool_drvinfo *info)
{



}

static u32 vis_get_link(struct net_device *ndev)
{



}

static void vis_get_ethtool_stats(struct net_device *ndev,
    struct ethtool_stats *stats, u64 *data)
{


}

static int vis_get_link_ksettings(struct net_device *ndev,
    struct ethtool_link_ksettings *cmd)
{



}

static int vis_read_sfp_module_eeprom_info(struct visroce_dev *vdev,
    u8 i2c_addr, u16 start, u16 data_length, u8 *buf)
{


}

static int vis_get_module_info(struct net_device *netdev,
    struct ethtool_modinfo *e_modinfo)
{


}


static int vis_get_module_eeprom(struct net_device *netdev,
    struct ethtool_eeprom *eeprom, u8 *data2user)
{


}


static const struct ethtool_ops vis_ethtool_ops = {
    .get_drvinfo = vis_get_drvinfo,
    .get_link = vis_get_link,
    .get_ethtool_stats = vis_get_ethtool_stats,
    .get_link_ksettings = vis_get_link_ksettings,
    .get_module_info = vis_get_module_info,
    .get_module_eeprom = vis_get_module_eeprom,
};

struct vis_dev *vis_alloc_net_device(u32 devfn)
{
    struct net_device *ndev;
    struct vis_dev *vdev;

    ndev = alloc_etherdev(sizeof(struct vis_dev));
    if(!ndev) {
        return NULL;
    }

    //ndev->mtu =
    ndev->addr_len = ETH_ALEN;
    ndev->netdev_ops = &vis_net_ops;
    ndev->ethtool_ops = &vis_ethtool_ops;

    vdev = netdev_priv(ndev);
    memset(vdev, 0, sizeof(struct vis_dev));

    vdev->ndev = ndev;




    return vdev;
}

